package cn.hzking.gjmall.net.https;

import android.content.Context;

import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.CertificateFactory;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

/**
 * Created by Administrator on 2018/1/20.
 */

public class HttpsFfactory {

    //绑定证书

    /**
     *
     * @param context 上下文对象
     * @param certificates 证书路径(R.raw.**),证书格式为bks格式
     * @return
     */
    public static SSLSocketFactory getSSLSocketFactory(Context context, int certificates) {

        if (context == null) {
            throw new NullPointerException("context == null");
        }

        //CertificateFactory用来证书生成
        CertificateFactory certificateFactory;
        try {
            certificateFactory = CertificateFactory.getInstance("X.509");
            //Create a KeyStore containing our trusted CAs
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

            //读取本地证书
            InputStream is = context.getResources().openRawResource(certificates);
            //第二个参数是证书密码
            keyStore.load(is, "123456".toCharArray());

            if (is != null) {
                is.close();
            }

            //Create a TrustManager that trusts the CAs in our keyStore(自定义证书信任处理器工厂类)
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            //把自定义证书的keystrore传入工厂类
            trustManagerFactory.init(keyStore);

            //Create an SSLContext that uses our TrustManager
            SSLContext sslContext = SSLContext.getInstance("TLS");//优先配置SSL,SSL无效可以配置TLS
            //第二个参数是用自定义TrustManager代替系统默认的信任管理器
            //修改android中SSLContext自带的TrustManager以便能让我们的签名通过验证。
            sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
            return sslContext.getSocketFactory();

        } catch (Exception e) {

        }
        return null;
    }

    //构造HostnameVerifier(过滤掉这一个主机名的url)
    public static HostnameVerifier getHostnameVerifier(final String hostUrls) {
        HostnameVerifier TRUSTED_VERIFIER = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                boolean ret = false;//返回false验证没通过
             //   Logger.e(hostname);
                if (hostUrls.equalsIgnoreCase(hostname)) {
                    ret = true; //返回true验证通过
                }

                return ret;
            }
        };
        return TRUSTED_VERIFIER;

    }

    //构造HostnameVerifier(过滤掉多个个主机名的url)
    protected static HostnameVerifier getHostnameVerifier(final String[] hostUrls) {
        HostnameVerifier TRUSTED_VERIFIER = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                //Logger.e(hostname);
                boolean ret = false;
                for (String host : hostUrls) {
                    if (host.equalsIgnoreCase(hostname)) {
                        //自行添加判断逻辑，true->Safe，false->unsafe
                        ret = true;
                    }
                }
                return ret;
            }
        };
        return TRUSTED_VERIFIER;


    }

    //绑定证书(传入数组)(存在问题,暂时不使用此方法)
    protected static SSLSocketFactory getSSLSocketFactory(Context context, int[] certificates) {
        if (context == null) {
            throw new NullPointerException("context == null");
        }
        CertificateFactory certificateFactory;
        try {
            certificateFactory = CertificateFactory.getInstance("X.509");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null, null);
            for (int i = 0; i < certificates.length; i++) {
                InputStream certificate = context.getResources().openRawResource(certificates[i]);
                keyStore.setCertificateEntry(String.valueOf(i), certificateFactory.generateCertificate(certificate));
                if (certificate != null) {
                    certificate.close();
                }
            }
            SSLContext sslContext = SSLContext.getInstance("TLS");
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
